<?php
namespace App\Services;
use Alipay\EasySDK\Kernel\Factory;
use Alipay\EasySDK\Kernel\Config;
use Illuminate\Support\Facades\Log;

class AlipayService
{
    public const NOTIFY_DEFAULT = 1;
    public const NOTIFY_ALTERNATE = 2;

    protected $config;
    protected $returnUrl;
    protected $h5QuitUrl;
    protected $h5ReturnUrl;

    public function __construct(int $notifyType = self::NOTIFY_DEFAULT)
    {

        $this->initializeConfig($notifyType);
        $this->loadUrlConfigs($notifyType);
        Factory::setOptions($this->config);
    }

    protected function initializeConfig(int $notifyType): void
    {
        $this->config = new Config();
        $this->config->protocol = 'https';
        $this->config->gatewayHost = $this->resolveGatewayHost();
        $this->config->signType = 'RSA2';
        $this->config->appId = config('services.alipay.app_id');
        $this->config->merchantPrivateKey = config('services.alipay.private_key');
        $this->config->alipayPublicKey = config('services.alipay.public_key');
        $this->config->notifyUrl = $this->resolveNotifyUrl($notifyType);
        $this->config->charset = 'UTF-8';
        $this->config->postCharset = 'UTF-8';
    }

    protected function resolveGatewayHost(): string
    {
        return config('services.alipay.env') === 'dev'
            ? 'openapi-sandbox.dl.alipaydev.com'
            : 'openapi.alipay.com';
    }

    protected function resolveNotifyUrl(int $notifyType): null|string
    {
        $configMap = [
            self::NOTIFY_DEFAULT => 'alipay',
            self::NOTIFY_ALTERNATE => 'alipay_coupon',
        ];

        if (!isset($configMap[$notifyType])) {
            Log::channel('alipayResult')->info('未找到相应异步回调配置', ['alipay_type'=>$notifyType]);
            return null;
        }
        $serviceKey = $configMap[$notifyType];
        return config("services.{$serviceKey}.notify_url");
    }

    protected function loadUrlConfigs($notifyType): void
    {
        $configMap = [
            self::NOTIFY_DEFAULT => 'alipay',
            self::NOTIFY_ALTERNATE => 'alipay_coupon',
        ];

        if (!isset($configMap[$notifyType])) {
            Log::channel('alipayResult')->info('未找到相应回调地址配置', ['alipay_type'=>$notifyType]);
            return;
        }
        $serviceKey = $configMap[$notifyType];
        $this->returnUrl = config("services.{$serviceKey}.return_url");
        $this->h5QuitUrl = config("services.{$serviceKey}.h5_quit_url");
        $this->h5ReturnUrl = config("services.{$serviceKey}.h5_return_url");
    }

    public function webPay(string $orderNo, float $amount, string $subject)
    {
        return Factory::payment()->page()
            ->optional('qr_pay_mode', '4')
            ->pay($subject, $orderNo, $amount, $this->returnUrl);
    }

    public function h5Pay(string $orderNo, float $amount, string $subject,$passBackArr)
    {
        return Factory::payment()->wap()
            ->optional('timeout_express', '5m')
            ->optional('user_agent', $_SERVER['HTTP_USER_AGENT'] ?? '')
            ->pay(
                $subject,
                $orderNo,
                $amount,
                $this->h5QuitUrl,
                $this->h5ReturnUrl,
                $passBackArr
            );
    }

    public function validateSign(array $params): bool
    {
        $verified = Factory::payment()->common()->verifyNotify($params);

        if (!$verified) {
            Log::channel('alipayResult')->info('支付宝验签失败', $params);
        }

        return $verified;
    }
}
